package org.sam.swing.table.defaultImpl;

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.swing.JOptionPane;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.table.TableColumnExt;
import org.sam.swing.action.JSFileImportActionListener;
import org.sam.swing.table.JSTableColumn;
import org.sam.swing.table.JSTableColumnModel;
import org.sam.swing.table.JSTableModel;
import org.sam.swing.table.action.JSTableAction;
import org.sam.swing.table.verification.Verificatior;
import org.sam.swing.utils.ExcelUtil;

/**
 * 默认的使用table上的设置导入excel数据的操作
 * 
 * @author sam
 *
 */
public class DefaultImportListenerActionImpl implements JSTableAction, JSFileImportActionListener {

	/**
	 * 当前操作的表格对象
	 */
	private JXTable table;

	/**
	 * 导入失败的行
	 */
	private Set<Integer> failRow;

	/**
	 * {@inheritDoc} 当前操作的表格对象
	 */
	@Override
	public JXTable getTable() {
		return this.table;
	}

	/**
	 * {@inheritDoc} 当前操作的表格对象
	 */
	@Override
	public void setTable(JXTable table) {
		this.table = table;
	}

	/**
	 * 从哪行开始导入
	 */
	private int beginRow = 0;

	/**
	 * 从哪行开始导入
	 * 
	 * @return
	 */
	public int getBeginRow() {
		return beginRow;
	}

	/**
	 * 设置从第几行开始导入
	 * 
	 * @param beginRow
	 */
	public void setBeginRow(int beginRow) {
		this.beginRow = beginRow;
	}

	/**
	 * 默认的使用table上的设置导入excel数据的操作
	 * 
	 * @param table
	 */
	public DefaultImportListenerActionImpl(JXTable table) {
		this.setTable(table);
	}

	/**
	 * {@inheritDoc} 询问用户是否清空数据库中的数据
	 */
	@Override
	public boolean beforeImport() throws Exception {
		int result = JOptionPane.showConfirmDialog(null, "是否清空当前已存在数据？", "信息提示", JOptionPane.YES_NO_CANCEL_OPTION,
				JOptionPane.QUESTION_MESSAGE);

		if (result == JOptionPane.CANCEL_OPTION)
			return false;

		if (result == JOptionPane.YES_OPTION) {
			this.getTable().setRowFilter(null);
			JSTableModel<?> model = (JSTableModel<?>) this.getTable().getModel();
			for (int i = model.getRowCount() - 1; i >= 0; i--) {
				model.delete(i);
			}
		}

		return true;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void afterOpen(File file) throws Exception {
		Workbook workbok = ExcelUtil.getWorkbok(file);
		Sheet sheet = workbok.getSheetAt(0);

		JSTableColumnModel columnModel = (JSTableColumnModel) this.getTable().getColumnModel();
		List<TableColumnExt> visibleColumns = columnModel.getVisibleDataColumns();
		if (visibleColumns == null || visibleColumns.isEmpty())
			throw new RuntimeException("无可见列");

		// 排一下序，让他
		if (visibleColumns.size() >= 2) {
			Collections.sort(visibleColumns, (n1, n2) -> Integer.compare(n1.getModelIndex(), n2.getModelIndex()));
		}

		JSTableModel<?> model = (JSTableModel<?>) this.getTable().getModel();
		int lastRow = sheet.getLastRowNum();
		failRow = new TreeSet<>();

		for (int i = this.getBeginRow(); i <= lastRow; i++) {
			boolean append = true;
			Row row = sheet.getRow(i);
			Object[] appendRow = new Object[visibleColumns.size()];

			try {
				for (int j = 0, iCount = visibleColumns.size(); j < iCount; j++) {
					// 这个单元格赋值
					JSTableColumn col = (JSTableColumn) visibleColumns.get(j);
					Verificatior verficator = col.getVerficator();
					Object value = ExcelUtil.getValue(row.getCell(j), model.getColumnClass(col.getModelIndex()),
							col.getDefaultValue());

					if (verficator != null) {
						if (verficator.verificat(value)) {
							appendRow[j] = value;
						} else {
							append = false;
							break;
						}
					} else {
						appendRow[j] = value;
					}
				}

				// 插入数据
				if (append) {
					append = model.append();
					if (!append)
						throw new RuntimeException("插入第" + i + "行失败");

					int iRow = model.getRowCount() - 1;

					for (int j = 0, iCount = visibleColumns.size(); j < iCount; j++) {
						JSTableColumn col = (JSTableColumn) visibleColumns.get(j);
						model.setValueAt(appendRow[j], iRow, col.getModelIndex());
					}
				} else {
					failRow.add(i + 1);
				}
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @throws Exception
	 */
	@Override
	public void afterDone() throws Exception {

		String msg = "";
		if (failRow.size() > 0 && failRow.size() <= 10) {
			msg = "本次导入失败excel数据行有：" + StringUtils.join(failRow, ",") + "\r\n";
		} else if (failRow.size() > 10) {
			msg = "本次导入失败excel数据总行数有：[" + failRow.size() + "],具体行号复制到剪贴板。\r\n";
			Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
			StringSelection paste = new StringSelection(StringUtils.join(failRow, "\r\n"));
			clipboard.setContents(paste, new ClipboardOwner() {
				
				@Override
				public void lostOwnership(Clipboard paramClipboard, Transferable paramTransferable) {
					
				}
			});
		}
		msg += "已经导入完成，是否马上保存入库？";

		int result = JOptionPane.showConfirmDialog(null, msg, "信息提示", JOptionPane.YES_NO_OPTION,
				JOptionPane.QUESTION_MESSAGE);

		if (result == JOptionPane.YES_OPTION) {
			JSTableModel<?> model = (JSTableModel<?>) this.getTable().getModel();
			if (model.update()) {
				JOptionPane.showMessageDialog(null, "保存成功");
			} else {
				JOptionPane.showMessageDialog(null, "保存失败");
			}
			model.setEditable(false);
		}
	}

}
